/*
 * <h3>Title:wheel-parent系统</h3>
 * <p>Copyright (c) 2019, wnfbx@163.com. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package com.wheel.autoconfigure.dynamicdatasource.configbinder;

import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertyNameAliases;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;

import javax.sql.DataSource;
import java.util.Map;

/**
 * <dt>Description:DynamicConfigurationPropertiesBinder</dt>
 * <dd>把数据源的配置绑定到数据源上</dd>
 *
 * @author wnfbx@163.com
 * @version 1.0 <i>2019/12/31 11:07</i>
 * @since jdk1.7+
 */
public class DynamicConfigurationPropertiesBinder {

    /**
     * 别名
     */
    public final static ConfigurationPropertyNameAliases aliases = new ConfigurationPropertyNameAliases();
    public final static String ALIASE_NAME_URL = "url";
    public final static String ALIASE_NAME_USERNAME = "username";

    static {
        aliases.addAliases(ALIASE_NAME_URL, "jdbc-url");
        aliases.addAliases(ALIASE_NAME_USERNAME, "user");
    }

    private DynamicConfigurationPropertiesBinder() {

    }

    public static DynamicConfigurationPropertiesBinder create() {
        return new DynamicConfigurationPropertiesBinder();
    }

    public DataSource bind(DataSource result, Map<?, ?> properties) {
        ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
        Binder binder = new Binder(source.withAliases(aliases));
        return binder.bind(ConfigurationPropertyName.EMPTY, Bindable.ofInstance(result)).get();  //将参数绑定到对象
    }

    public <T extends DataSource> T bind(Class<T> clazz, Map<?, ?> properties) {
        ConfigurationPropertySource source = new MapConfigurationPropertySource(properties);
        Binder binder = new Binder(source.withAliases(aliases));
        return binder.bind(ConfigurationPropertyName.EMPTY, Bindable.of(clazz)).get(); //通过类型绑定参数并获得实例对象
    }
}
